package org.mclll.xwangplugin.town.command.executor;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.mclll.xwangplugin.town.database.domain.TownApplyDO;
import org.mclll.xwangplugin.town.database.domain.TownDO;
import org.mclll.xwangplugin.town.database.domain.TownPlayerDO;
import org.mclll.xwangplugin.town.database.mapper.manage.TownApplyManage;
import org.mclll.xwangplugin.town.database.mapper.manage.TownManage;
import org.mclll.xwangplugin.town.database.mapper.manage.TownPlayerManage;
import org.mclll.xwangplugin.town.enums.ApplyStatus;
import org.mclll.xwangplugin.town.enums.ApplyType;
import org.mclll.xwangplugin.town.enums.PlayerTownIdentity;
import org.mclll.xwangplugin.town.lp.LuckPermsTown;
import org.mclll.xwangplugin.util.PlayerTools;

import java.util.Collections;
import java.util.List;

import static org.mclll.xwangplugin.town.config.TownContext.*;
import static org.mclll.xwangplugin.util.PlayerTools.getOfflineOrOnlinePlayerByUuid;

/**
 * @author: geduo
 * @date: 2023/9/23 20:11
 */
public class InviteAcceptExecutor {
    public static void accept(Player player, String[] args) {
        String playerUuid = player.getUniqueId().toString();
        if (args.length != 2) {
            player.sendMessage(ACCEPT_COMMAND_FORMAT);
            return;
        }
        TownPlayerDO senderPlayer = TownPlayerManage.selectByUuid(playerUuid);
        if ("list".equals(args[1])) {
            if (senderPlayer.getIdentity() == PlayerTownIdentity.LEADER) {
                sendApplyList(player, playerUuid);
                return;
            } else {
                player.sendMessage(NOT_PERMISSION);
                return;
            }
        }
        Integer i = null;
        try {
            i = Integer.valueOf(args[1]);
        } catch (NumberFormatException e) {
            player.sendMessage(ACCEPT_COMMAND_FORMAT);
            return;
        }
        TownApplyDO selectParam = new TownApplyDO();
        selectParam.setId(i);
        selectParam.setStatus(ApplyStatus.APPLYING);
        List<TownApplyDO> townApplyList = TownApplyManage.selectList(selectParam);
        if (townApplyList.isEmpty()) {
            player.sendMessage(APPLY_ID_NOT_FOUND);
            return;
        }
        TownApplyDO townApply = townApplyList.get(0);
        TownDO town = TownManage.selectByUuid(townApply.getTownUuid());
        if (
                (townApply.getType() == ApplyType.LEADER_INVITATION && !townApply.getPlayerUuid().equals(playerUuid)) ||
                (townApply.getType() == ApplyType.PLAYER_APPLICATION && !town.getLeaderUuid().equals(playerUuid))
        ) {
            player.sendMessage(NOT_PERMISSION);
            return;
        }
        townApply.setStatus(ApplyStatus.AGREED);
        TownApplyManage.updateById(townApply);
        // 如果该玩家有其他申请记录，全部拒绝
        {
            TownApplyDO where = new TownApplyDO();
            where.setPlayerUuid(townApply.getPlayerUuid());
            where.setStatus(ApplyStatus.APPLYING);
            TownApplyDO param = new TownApplyDO();
            param.setStatus(ApplyStatus.REFUSED);
            TownApplyManage.update(param, where);
        }
        TownPlayerDO townPlayer = new TownPlayerDO();
        townPlayer.setTownUuid(townApply.getTownUuid());
        townPlayer.setIdentity(PlayerTownIdentity.MEMBER);
        townPlayer.setUuid(townApply.getPlayerUuid());
        TownPlayerManage.updateByUuid(townPlayer);
        // 权限部分
        LuckPermsTown.addPlayerToTown(
                town.getName(),
                Collections.singletonList(PlayerTools.getOfflineOrOnlinePlayerByUuid(townApply.getPlayerUuid()).getName()))
        ;
        if (townApply.getType() == ApplyType.PLAYER_APPLICATION) {
            // 这里player是镇长，targetPlayer是被邀请的玩家
            OfflinePlayer targetPlayer = getOfflineOrOnlinePlayerByUuid(townApply.getPlayerUuid());
            player.sendMessage(String.format(PLAYER_JOIN_TOWN_SUCCESS, targetPlayer.getName()));
            if (targetPlayer.isOnline()) {
                ((Player) targetPlayer).sendMessage(String.format(PLAYER_JOIN_TOWN_SUCCESS_SEND_PLAYER, town.getName()));
            }
        } else if (townApply.getType() == ApplyType.LEADER_INVITATION) {
            // 这里player是被邀请的玩家，targetPlayer是镇长
            OfflinePlayer targetPlayer = getOfflineOrOnlinePlayerByUuid(town.getLeaderUuid());
            player.sendMessage(String.format(INVITE_PLAYER_SUCCESS_SEND_PLAYER, town.getName()));
            if (targetPlayer.isOnline()) {
                ((Player) targetPlayer).sendMessage(String.format(INVITE_PLAYER_SUCCESS, player.getName()));
            }
        }

    }

    private static void sendApplyList(Player player, String playerUuid) {
        TownDO searchParam = new TownDO();
        searchParam.setLeaderUuid(playerUuid);
        TownDO town = TownManage.selectList(searchParam).get(0);

        TownApplyDO selectParam = new TownApplyDO();
        selectParam.setTownUuid(town.getUuid());
        selectParam.setType(ApplyType.PLAYER_APPLICATION);
        selectParam.setStatus(ApplyStatus.APPLYING);
        List<TownApplyDO> townApplyList = TownApplyManage.selectList(selectParam);
        TextComponent.Builder message = Component.text().append(Component.text(APPLY_LIST_TITLE));
        for (TownApplyDO townApply : townApplyList) {
            OfflinePlayer targetPlayer = getOfflineOrOnlinePlayerByUuid(townApply.getPlayerUuid());
            message.appendNewline()
                    .append(Component.text(targetPlayer.getName()))
                    .append(Component.text("    "))
                    .append(
                            Component.text(CONFIRM_BUTTON)
                                    .clickEvent(ClickEvent.runCommand("/poitown accept " + townApply.getId()))
                                    .hoverEvent(HoverEvent.showText(Component.text(CONFIRM_BUTTON)))
                    )
                    .append(Component.text("    "))
                    .append(
                            Component.text(CANCEL_BUTTON)
                                    .clickEvent(ClickEvent.runCommand("/poitown reject " + townApply.getId()))
                                    .hoverEvent(HoverEvent.showText(Component.text(CANCEL_BUTTON)))
                    )
            ;
        }
        player.sendMessage(message.build());
    }
}
